import logging

from core.entities.account_role import AccountWrap
from extensions.ext_database import db
from models.robot.intent_reco import IntentRecoTerms

class IntentRecTermService:
    # @staticmethod
    # def create_segment(tenant_id, account_id, args: dict, document: DatasetDocument, dataset: Dataset, extra_info: dict):
    #     content = args["content"]
    #     doc_id = str(uuid.uuid4())
    #     segment_hash = helper.generate_text_hash(content)
    #     tokens = 0
    #     if dataset.indexing_technique == "high_quality":
    #         model_manager = ModelManager()
    #         embedding_model = model_manager.get_model_instance(
    #             tenant_id=tenant_id,
    #             provider=dataset.embedding_model_provider,
    #             model_type=ModelType.TEXT_EMBEDDING,
    #             model=dataset.embedding_model,
    #         )
    #         # calc embedding use tokens
    #         tokens = embedding_model.get_text_embedding_num_tokens(texts=[content])[
    #             0]
    #     lock_name = "add_segment_lock_document_id_{}".format(document.id)
    #     with redis_client.lock(lock_name, timeout=600):
    #         max_position = (
    #             db.session.query(func.max(DocumentSegment.position))
    #             .filter(DocumentSegment.document_id == document.id)
    #             .scalar()
    #         )
    #         segment_document = DocumentSegment(
    #             tenant_id=tenant_id,
    #             dataset_id=document.dataset_id,
    #             document_id=document.id,
    #             index_node_id=doc_id,
    #             index_node_hash=segment_hash,
    #             position=max_position + 1 if max_position else 1,
    #             content=content,
    #             word_count=len(content),
    #             tokens=tokens,
    #             status="completed",
    #             indexing_at=datetime.datetime.now(
    #                 datetime.UTC).replace(tzinfo=None),
    #             completed_at=datetime.datetime.now(
    #                 datetime.UTC).replace(tzinfo=None),
    #             created_by=account_id,
    #         )
    #         if document.doc_form == "qa_model":
    #             segment_document.word_count += len(args["answer"])
    #             segment_document.answer = args["answer"]

    #         db.session.add(segment_document)
    #         # update document word count
    #         document.word_count += segment_document.word_count
    #         db.session.add(document)
    #         db.session.commit()

    #         # save vector index
    #         try:
    #             IntentVectorService.create_segments_vector(
    #                 [args["keywords"]], [segment_document], dataset, document.doc_form, [extra_info])
    #         except Exception as e:
    #             logging.exception("create segment index failed")
    #             segment_document.enabled = False
    #             segment_document.disabled_at = datetime.datetime.now(
    #                 datetime.UTC).replace(tzinfo=None)
    #             segment_document.status = "error"
    #             segment_document.error = str(e)
    #             db.session.commit()
    #         segment = db.session.query(DocumentSegment).filter(
    #             DocumentSegment.id == segment_document.id).first()
    #         return segment
    
    # @staticmethod
    # def _apply_term_to_ds(operator:Account,term:IntentRecoTerms):
    #     group_cmd_map = db.session.query(IntentRecMap).filter(IntentRecMap.cmd_id == term.cmd_id).first()
    #     if not group_cmd_map:
    #         return
        
    #     group = db.session.get(IntentRecGroup,group_cmd_map.group_id)
    #     if not group:
    #         raise BadRequest("Group not found")
    #     dataset = DatasetService.get_dataset(group.dataset_id)
    #     if not dataset:
    #         raise ValueError(f"Dataset {group.dataset_id} not found")
    #     document = DocumentService.get_document(
    #         group.dataset_id, group.document_id)
    #     if not document:
    #         raise ValueError(f"Document {group.document_id} not found")
        
    #     result = IntentRecGroupService.perform_hit_testing(
    #                 operator, dataset, term.term)
    #     found = False
    #     if result:
    #         found, segment_id, content = result
    #     if found:
    #         term.status = RobIntRecTermStatus.FOUND_SAME
    #         term.segment_id = segment_id
    #         term.same_content = content
    #         db.session.commit()
    #         logging.info(
    #             f"term {term.term} found in segment {segment_id}:content:{content}")
    #     else:
    #         try:
    #             segment = IntentRecTermService.create_segment(
    #                 operator.current_tenant_id,
    #                 operator.id,
    #                 {
    #                     "content": term.term,
    #                     "answer": str(term.cmd_id),
    #                     "keywords": []
    #                 }, document, dataset,
    #                 {"cmd_id": str(term.cmd_id),
    #                     "term_id": str(term.id)}
    #             )
    #             if segment:
    #                 term.segment_id = segment.id
    #                 term.status = RobIntRecTermStatus.DONE
    #                 db.session.flush()
    #                 logging.info(click.style("Segment {} created:{}".format(
    #                     segment.id, segment.content), fg="green"))
    #             else:
    #                 rob_func = db.session.get(RobFuncs,term.cmd_id)
    #                 logging.info(click.style("Segment {}:{} has not created, pass.".format(
    #                     rob_func.name if rob_func else "Unknow CMD", term.term), fg="red"))
    #         except Exception as e:
    #             logging.error(f"create segment error:{e}")
    #             term.status = RobIntRecTermStatus.FAILED

    @staticmethod
    def create_term(operator: AccountWrap,func_id:str,term_str:str)->IntentRecoTerms:
        try:
            term = db.session.query(IntentRecoTerms).filter(
                IntentRecoTerms.tenant_id==operator.current_tenant_id,
                IntentRecoTerms.term==term_str,
                IntentRecoTerms.cmd_id==func_id
            ).first()
            if not term:
                new_term = IntentRecoTerms(
                    tenant_id=operator.current_tenant_id, # type: ignore
                    cmd_id = func_id, # type: ignore
                    term = term_str, # type: ignore
                    hit_count = 0, # type: ignore
                    created_by = operator.id # type: ignore
                )
                db.session.add(new_term)
                # db.session.flush()
                db.session.commit()
                
                term = new_term
            # IntentRecTermService._apply_term_to_ds(operator,term)
            return term
        except Exception as e:
            db.session.rollback()
            raise e
        
    @staticmethod
    def create_terms(operator: AccountWrap,func_id:str,terms:list[str])->list[IntentRecoTerms]:
        try:
            rets = []
            for term in terms:
                new_term = IntentRecTermService.create_term(operator,func_id,term)
                rets.append(new_term)
            db.session.commit()
            return rets
        except Exception as e:
            db.session.rollback()
            raise e
        
    @staticmethod
    def get_terms_by_cmd(cmd_id:str,term:str|None,page:int=-1,page_size:int=-1)->dict:
        try:
            query = db.session.query(IntentRecoTerms).filter(IntentRecoTerms.cmd_id == cmd_id)
            if term:
                query = query.filter(IntentRecoTerms.term.like(f"%{term}%"))
            total = query.count()
            hasMore = False
            if page >= 0 and page_size >= 0:
                query = query.offset((page-1) * page_size).limit(page_size)
                hasMore = total > page_size * page
            terms = query.all()
            return {
                "total": total,
                "hasMore": hasMore,
                "data":terms,
            }
        except Exception as e:
            logging.error(e)
            return {
                "total": 0,
                "hasMore": False,
                "data": [],
                "error": str(e)
            }
    